package server;



import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;

/** This class puts together all the customizable server components and manages services execution.
 */
public class Server {

	public static Server sharedInstance = new Server();
	private static final String SERVER_ADDRESS = "treefinder.bounceme.net";
	private InetAddress address = null;
	
	private ArrayList<Service> services = new ArrayList<Service>();
	

	private boolean parametersSet = false;

	private FeedbackManager feedbackManager;
	private UsersManager usersManager;
	private SingleProtocol protocol;
	

	private Server() {
		try {
			address = InetAddress.getByName(SERVER_ADDRESS);
		} catch (UnknownHostException e) {
			try {
				address = InetAddress.getLocalHost();
			} catch (UnknownHostException e1) {
				e1.printStackTrace();
			}
			e.printStackTrace();
		}
	}

	/**
	 * Set the components for this server. If these are not set before starting the server, an exception is raised.
	 * @param feedbackManager A feedback Manager
	 * @param usersManager A User Manager
	 * @param protocol A protocol
	 */
	public void setParameters (FeedbackManager feedbackManager, UsersManager usersManager, SingleProtocol protocol) {

		this.feedbackManager = feedbackManager;
		this.usersManager = usersManager;
		this.protocol = protocol;
		
		protocol.initialize();
		
		feedbackManager.printMessage("Server started...", false);
		
		parametersSet = true;
	}
	
	public InetAddress getServerAddress() {
		return address;
	}

	/** Add a service to the service list. They will be executed on server start.
	 * @param service A service
	 */
	public void addService (Service service) {
		services.add(service);
	}


	public void start() {
		
		try {

			if (parametersSet == false)
				throw new ServerInitializingException("Parameters not set. Set the parameters before starting server.");


			for (int i = 0; i < services.size(); i++) {
				services.get(i).start();
			}

			feedbackManager.printInfoMessage("DEFAULT PROTOCOL:");
			protocol.writeInfo();
			
		} catch (ServerInitializingException e1) {
			e1.printStackTrace();
		}

	}

	public void shutdown() {
		protocol.closeSockets();
		System.exit(0);
	}


	public FeedbackManager getFeedbackManager() {
		return feedbackManager;
	}


	public UsersManager getUsersManager() {
		return usersManager;
	}


	public SingleProtocol getSingleProtocol() {
		return protocol;
	}


	public static Server getSharedInstance() {
		return sharedInstance;
	}


}